home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * Mesa bindings for SciTech MGL
- *
- * Language: ANSI C
- * Environment: Any
- *
- * Description: Main Mesa 3D library interface between the MGL and
- * Mesa. For maximum peformance we call the MGL's internal
- * rendering functions directly so we can bypass all the
- * clipping and regular MGL API stuff as all that is already
- * handled by Mesa before the calls get here.
- *
- * Note also that all rendering is inherently single threaded
- * so we optimize for this case by using a global current
- * context structure.
- *
- * This module contains generic interface routines.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************************/
-
- #include "mgl/mmesap.h"
- #pragma hdrstop
- #include "GL/mglmesa.h"
- #include <string.h>
- #include <stdlib.h>
-
- /*--------------------------- Global Variables ----------------------------*/
-
- #ifdef __WINDOWS__
- MGLCallbacks _MGL_callbacks; /* MGL callback functions */
- #endif
- gmode_t _MGL_mi; /* MGL mode information */
- pixel_format_t _MGL_pf; /* MGL mode pixel format */
- vecs _MGL_vecs; /* MGL Rendering vectors */
- MGLRC _MM_rc; /* Current rendering context */
- MGLRC *_MM_rcPtr = NULL; /* Pointer to current context */
-
- /*------------------------- Implementation --------------------------------*/
-
- #pragma warn -par
-
- /**********************************************************************/
- /***** Miscellaneous device driver funcs *****/
- /**********************************************************************/
-
- static void begin(GLcontext *ctx,GLenum mode)
- /****************************************************************************
- *
- * Function: begin
- *
- * Description: Called when glBegin is called. We use this oportunity to
- * enable direct framebuffer access for our rendering functions.
- *
- ****************************************************************************/
- {
- // TODO: Call begin directAccess depending on the currently selected mode
- // and also the current rendering attributes (to determine if we need
- // to directly access the buffer. We need this to support VBE/AF.
- //
- // We should optimize this to have this code in here run fast, and
- // put the complicated code into the setup_DD_funcs to avoid the
- // overheads of checking in here.
-
- _MGL_vecs.beginDirectAccess();
- }
-
- static void end(GLcontext *ctx)
- /****************************************************************************
- *
- * Function: end
- *
- * Description: Called when glEnd is called. We use this oportunity to
- * disable direct framebuffer access for our rendering
- * functions.
- *
- ****************************************************************************/
- {
- _MGL_vecs.endDirectAccess();
- }
-
- static void finish(GLcontext *ctx)
- /****************************************************************************
- *
- * Function: finish
- *
- * Description: Called when glFinish is called. We simply do nothing here.
- *
- ****************************************************************************/
- {
- }
-
- static void flush(GLcontext *ctx)
- /****************************************************************************
- *
- * Function: flush
- *
- * Description: Called when glFlush is called. We simply do nothing here
- *
- ****************************************************************************/
- {
- }
-
- static void clear_index(GLcontext *ctx, GLuint index)
- /****************************************************************************
- *
- * Function: clear_index
- * Parameters: index - New color index for buffer clears
- *
- * Description: Sets the current buffer clear color for color index buffers.
- *
- ****************************************************************************/
- {
- RC.clearColor = index;
- }
-
- static void clear_color(GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a)
- /****************************************************************************
- *
- * Function: clear_color
- * Parameters: r,g,b,a - New RGBA color values for buffer clears
- *
- * Description: Set the current buffer clear color for TrueColor buffers.
- * Note that Mesa passes us color values pre-scaled to the
- * proper number of color bits:
- *
- * [0,ctx->Visual->RedScale]
- * [0,ctx->Visual->GreenScale]
- * [0,ctx->Visual->BlueScale]
- * [0,ctx->Visual->AlphaScale]
- *
- ****************************************************************************/
- {
- RC.clearColor = MGL_packColorFast(&PF,r,g,b);
- }
-
- static GLbitfield clear(GLcontext *ctx, GLbitfield mask, GLboolean all, GLint x,
- GLint y, GLint width, GLint height)
- /****************************************************************************
- *
- * Function: clear
- * Parameters: all - True to clear entire buffer
- * x,y,width,height - Rectangle to clear
- *
- * Description: Clears the buffer in the current clear color
- *
- ****************************************************************************/
- {
- if (mask & GL_COLOR_BUFFER_BIT) {
- VECS.setColor(RC.clearColor);
- if (all)
- VECS.solid.fillRect(0,0,MI.xRes+1,MI.yRes+1);
- else
- VECS.solid.fillRect(x,y,x+width,y+height);
- }
- return mask & (~GL_COLOR_BUFFER_BIT);
- }
-
- static void set_index(GLcontext *ctx, GLuint index)
- /****************************************************************************
- *
- * Function: clear_index
- * Parameters: index - New color index
- *
- * Description: Sets the current solid color for color index buffers.
- *
- ****************************************************************************/
- {
- RC.color = index;
- }
-
- static void set_color(GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a)
- /****************************************************************************
- *
- * Function: set_color
- * Parameters: r,g,b,a - New RGBA color value
- *
- * Description: Set the current solid color for TrueColor buffers.
- * Note that Mesa passes us color values pre-scaled to the
- * proper number of color bits:
- *
- * [0,ctx->Visual->RedScale]
- * [0,ctx->Visual->GreenScale]
- * [0,ctx->Visual->BlueScale]
- * [0,ctx->Visual->AlphaScale]
- *
- ****************************************************************************/
- {
- RC.color = MGL_packColorFast(&PF,r,g,b);
- RC.red = r;
- RC.green = g;
- RC.blue = b;
- }
-
- static GLboolean index_mask(GLcontext *ctx, GLuint mask)
- /****************************************************************************
- *
- * Function: index_mask
- * Parameters: mask - Color index mask
- * Returns: True if we implement masking, false if not
- *
- * Description: Implements color index masking ala glIndexMask if possible.
- * We currently return false for this function.
- *
- ****************************************************************************/
- {
- return GL_FALSE;
- }
-
- static GLboolean color_mask(GLcontext *ctx,
- GLboolean rmask, GLboolean gmask,GLboolean bmask, GLboolean amask)
- /****************************************************************************
- *
- * Function: color_mask
- * Parameters: rmask - Red mask
- * gmask - Green mask
- * bmask - Blue mask
- * amask - Alpha mask
- * Returns: True if we implement masking, false if not
- *
- * Description: Implements RGB color masking ala glColorMask if possible.
- * We currently return false for this function.
- *
- ****************************************************************************/
- {
- return GL_FALSE;
- }
-
- static GLboolean logicop(GLcontext *ctx, GLenum op)
- /****************************************************************************
- *
- * Function: logicop
- * Parameters: op - New logic op to enable
- * Returns: True if we implement masking, false if not
- *
- * Description: Implements logic operations ala glLogicOp if possible. For
- * op's that we dont support we simply return GL_FALSE and it
- * is implemented in software by Mesa.
- *
- ****************************************************************************/
- {
- #if 0
- int mode;
-
- switch (op) {
- case GL_COPY: mode = MGL_REPLACE_MODE; break;
- case GL_AND: mode = MGL_AND_MODE; break;
- case GL_OR: mode = MGL_OR_MODE; break;
- case GL_XOR: mode = MGL_XOR_MODE; break;
- default: return GL_FALSE;
- }
- DC.r.setWriteMode(mode);
- return GL_TRUE;
- #else
- return GL_FALSE;
- #endif
- }
-
- static void dither(GLcontext *ctx, GLboolean enable)
- /****************************************************************************
- *
- * Function: dither
- * Parameters: enable - True to enable dithering, false to disable it
- *
- * Description: Enables dithering mode if applicable.
- *
- ****************************************************************************/
- {
- if (enable)
- RC.pixelformat = RC.dithered_pf;
- else
- RC.pixelformat = RC.undithered_pf;
- setup_DD_pointers(ctx);
- }
-
- static GLboolean set_buffer(GLcontext *ctx, GLenum mode)
- /****************************************************************************
- *
- * Function: set_buffer
- * Parameters: mode - Buffer mode to enable
- *
- * Description: Sets the buffer access mode to the front buffer or the
- * back buffer for the application. The MGL always allows
- * direct access to both buffers in double buffered fullscreen
- * modes, but when rendering to a memory device context (ie:
- * when rendering in a window in the windows environment) we
- * only have a single buffer available.
- *
- ****************************************************************************/
- {
- if (!RC.gl_vis->DBflag) {
- MGL_makeCurrentDC(RC.dc);
- return (mode = GL_FRONT);
- }
- if (RC.dc->mi.maxPage > 0) {
- /* Hardware page flipping */
- if (mode == GL_FRONT)
- MGL_setActivePage(RC.dc,RC.frontbuffer);
- else if (mode == GL_BACK)
- MGL_setActivePage(RC.dc,RC.backbuffer);
- else
- return GL_FALSE;
- }
- if (RC.memdc) {
- /* Software double buffering using a memory DC. In some cases
- * we may not be able to access the display memory surface for the
- * front buffer in which case this will fail.
- */
- if (mode == GL_FRONT && (MGL_surfaceAccessType(RC.dc) != MGL_NO_ACCESS))
- MGL_makeCurrentDC(RC.dc);
- else if (mode == GL_BACK)
- MGL_makeCurrentDC(RC.memdc);
- else
- return GL_FALSE;
- }
- else {
- /* Hardware page flipping only */
- MGL_makeCurrentDC(RC.dc);
- }
- RC.bufferMode = mode;
- setup_DD_pointers(ctx);
- return GL_TRUE;
- }
-
- static void get_buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)
- /****************************************************************************
- *
- * Function: get_buffer_size
- * Parameters: width - Place to store buffer width
- * height - Place to store buffer height
- *
- * Description: Returns the current buffer width and height. We simply
- * return the currently active device context's width and
- * height, which will change if the buffer is resized in a
- * windowed environment.
- *
- ****************************************************************************/
- {
- if (MI.xRes != RC.dispdc->mi.xRes || MI.yRes != RC.dispdc->mi.yRes) {
- MI.xRes = RC.dispdc->mi.xRes;
- MI.yRes = RC.dispdc->mi.yRes;
-
- /* Resize our system memory back buffer if we have one */
- if (RC.memdc) {
- MGL_destroyDC(RC.memdc);
- RC.memdc = MGL_createMemoryDC(MI.xRes+1,MI.yRes+1,MI.bitsPerPixel,&PF);
- if (!RC.memdc)
- exit(1);
- RC.dc = RC.memdc;
- if (RC.dispdc->mi.bitsPerPixel == 8) {
- palette_t pal[256];
- MGL_getPalette(RC.dispdc,pal,256,0);
- MGL_setPalette(RC.memdc,pal,256,0);
- MGL_realizePalette(RC.memdc,256,0,-1);
- }
- MI = RC.dc->mi;
- }
- }
- *width = MI.xRes+1;
- *height = MI.yRes+1;
- RC.bottom = MI.yRes;
- }
-
- /**********************************************************************/
- /*** Point rendering ***/
- /**********************************************************************/
-
- PUBLIC points_func mmesa_get_points_func(GLcontext *ctx)
- /****************************************************************************
- *
- * Function: mmesa_get_points_func
- * Parameters: ctx - Context to examine
- *
- * Description: Analyze context state to see if we can provide a fast points
- * drawing function, like those in points.c. Otherwise, return
- * NULL.
- *
- ****************************************************************************/
- {
- #if 0
- if (ctx->Point.Size == 1.0F && !ctx->Point.SmoothFlag && ctx->RasterMask == 0
- && !ctx->Texture.Enabled) {
- return draw_points;
- }
- #endif
- return NULL;
- }
-
- /**********************************************************************/
- /*** Line rendering ***/
- /**********************************************************************/
-
- PUBLIC line_func mmesa_get_line_func(GLcontext *ctx)
- /****************************************************************************
- *
- * Function: mmesa_get_line_func
- * Parameters: ctx - Context to examine
- *
- * Description: Analyze context state to see if we can provide a fast line
- * drawing function, like those in lines.c. Otherwise, return
- * NULL.
- *
- ****************************************************************************/
- {
- #if 0
- XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- int depth = xmesa->xm_visual->visinfo->depth;
-
- if (ctx->Line.SmoothFlag) return NULL;
- if (ctx->Texture.Enabled) return NULL;
- if (ctx->Light.ShadeModel!=GL_FLAT) return NULL;
-
- if (xmesa->xm_buffer->buffer==XIMAGE
- && ctx->RasterMask==DEPTH_BIT
- && ctx->Depth.Func==GL_LESS
- && ctx->Depth.Mask==GL_TRUE
- && ctx->Line.Width==1.0F
- && ctx->Line.StippleFlag==GL_FALSE) {
- switch (xmesa->pixelformat) {
- case PF_TRUECOLOR:
- return flat_TRUECOLOR_z_line;
- case PF_8A8B8G8R:
- return flat_8A8B8G8R_z_line;
- case PF_8R8G8B:
- return flat_8R8G8B_z_line;
- case PF_5R6G5B:
- return flat_5R6G5B_z_line;
- case PF_DITHER:
- return (depth==8) ? flat_DITHER8_z_line : NULL;
- case PF_LOOKUP:
- return (depth==8) ? flat_LOOKUP8_z_line : NULL;
- case PF_HPCR:
- return flat_HPCR_z_line;
- default:
- return NULL;
- }
- }
- if (xmesa->xm_buffer->buffer==XIMAGE
- && ctx->RasterMask==0
- && ctx->Line.Width==1.0F
- && ctx->Line.StippleFlag==GL_FALSE) {
- switch (xmesa->pixelformat) {
- case PF_TRUECOLOR:
- return flat_TRUECOLOR_line;
- case PF_8A8B8G8R:
- return flat_8A8B8G8R_line;
- case PF_8R8G8B:
- return flat_8R8G8B_line;
- case PF_5R6G5B:
- return flat_5R6G5B_line;
- case PF_DITHER:
- return (depth==8) ? flat_DITHER8_line : NULL;
- case PF_LOOKUP:
- return (depth==8) ? flat_LOOKUP8_line : NULL;
- case PF_HPCR:
- return flat_HPCR_line;
- default:
- return NULL;
- }
- }
- if (xmesa->xm_buffer->buffer!=XIMAGE && ctx->RasterMask==0) {
- setup_x_line_options( ctx );
- return flat_pixmap_line;
- }
- #endif
- return NULL;
- }
-
- /**********************************************************************/
- /*** Triangle rendering ***/
- /**********************************************************************/
-
- triangle_func mmesa_get_triangle_func(GLcontext *ctx)
- {
- #if 0
- XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
- int depth = xmesa->xm_visual->visinfo->depth;
-
- if (ctx->Polygon.SmoothFlag) return NULL;
- if (ctx->Texture.Enabled) return NULL;
-
- if (xmesa->xm_buffer->buffer==XIMAGE) {
- if ( ctx->Light.ShadeModel==GL_SMOOTH
- && ctx->RasterMask==DEPTH_BIT
- && ctx->Depth.Func==GL_LESS
- && ctx->Depth.Mask==GL_TRUE
- && ctx->Polygon.StippleFlag==GL_FALSE) {
- switch (xmesa->pixelformat) {
- case PF_TRUECOLOR:
- return smooth_TRUECOLOR_z_triangle;
- case PF_8A8B8G8R:
- return smooth_8A8B8G8R_z_triangle;
- case PF_8R8G8B:
- return smooth_8R8G8B_z_triangle;
- case PF_5R6G5B:
- return smooth_5R6G5B_z_triangle;
- case PF_HPCR:
- return smooth_HPCR_z_triangle;
- case PF_DITHER:
- return (depth==8) ? smooth_DITHER8_z_triangle
- : smooth_DITHER_z_triangle;
- case PF_LOOKUP:
- return (depth==8) ? smooth_LOOKUP8_z_triangle : NULL;
- default:
- return NULL;
- }
- }
- if ( ctx->Light.ShadeModel==GL_FLAT
- && ctx->RasterMask==DEPTH_BIT
- && ctx->Depth.Func==GL_LESS
- && ctx->Depth.Mask==GL_TRUE
- && ctx->Polygon.StippleFlag==GL_FALSE) {
- switch (xmesa->pixelformat) {
- case PF_TRUECOLOR:
- return flat_TRUECOLOR_z_triangle;
- case PF_8A8B8G8R:
- return flat_8A8B8G8R_z_triangle;
- case PF_8R8G8B:
- return flat_8R8G8B_z_triangle;
- case PF_5R6G5B:
- return flat_5R6G5B_z_triangle;
- case PF_HPCR:
- return flat_HPCR_z_triangle;
- case PF_DITHER:
- return (depth==8) ? flat_DITHER8_z_triangle
- : flat_DITHER_z_triangle;
- case PF_LOOKUP:
- return (depth==8) ? flat_LOOKUP8_z_triangle : NULL;
- default:
- return NULL;
- }
- }
- if ( ctx->RasterMask==0 /* no depth test */
- && ctx->Light.ShadeModel==GL_SMOOTH
- && ctx->Polygon.StippleFlag==GL_FALSE) {
- switch (xmesa->pixelformat) {
- case PF_TRUECOLOR:
- return smooth_TRUECOLOR_triangle;
- case PF_8A8B8G8R:
- return smooth_8A8B8G8R_triangle;
- case PF_8R8G8B:
- return smooth_8R8G8B_triangle;
- case PF_5R6G5B:
- return smooth_5R6G5B_triangle;
- case PF_HPCR:
- return smooth_HPCR_triangle;
- case PF_DITHER:
- return (depth==8) ? smooth_DITHER8_triangle
- : smooth_DITHER_triangle;
- case PF_LOOKUP:
- return (depth==8) ? smooth_LOOKUP8_triangle : NULL;
- default:
- return NULL;
- }
- }
-
- if ( ctx->RasterMask==0 /* no depth test */
- && ctx->Light.ShadeModel==GL_FLAT
- && ctx->Polygon.StippleFlag==GL_FALSE) {
- switch (xmesa->pixelformat) {
- case PF_TRUECOLOR:
- return flat_TRUECOLOR_triangle;
- case PF_8A8B8G8R:
- return flat_8A8B8G8R_triangle;
- case PF_8R8G8B:
- return flat_8R8G8B_triangle;
- case PF_5R6G5B:
- return flat_5R6G5B_triangle;
- case PF_HPCR:
- return flat_HPCR_triangle;
- case PF_DITHER:
- return (depth==8) ? flat_DITHER8_triangle
- : flat_DITHER_triangle;
- case PF_LOOKUP:
- return (depth==8) ? flat_LOOKUP8_triangle : NULL;
- default:
- return NULL;
- }
- }
-
- return NULL;
- }
- else {
- /* pixmap */
- if (ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0) {
- setup_x_polygon_options( ctx );
- return flat_pixmap_triangle;
- }
- return NULL;
- }
- #endif
- return NULL;
- }
-
- /**********************************************************************/
- /*** Quad rendering ***/
- /**********************************************************************/
-
- quad_func mmesa_get_quad_func(GLcontext *ctx)
- {
- return NULL;
- }
-
- /**********************************************************************/
- /*** 2D Rectangle Rendering ***/
- /**********************************************************************/
-
- rect_func mmesa_get_rect_func(GLcontext *ctx)
- {
- return NULL;
- }
-
- /**********************************************************************/
- /***** Miscellaneous functions *****/
- /**********************************************************************/
-
- static const char *renderer_string(void)
- {
- return "SciTech MGL " MGL_VERSION_STR;
- }
-
- static void setup_DD_pointers(GLcontext *ctx)
- /****************************************************************************
- *
- * Function: setup_DD_pointer
- * Parameters: ctx - Device context to setup pointers for
- *
- * Description: Sets up all the device driver rendering pointers for the
- * current rendering state. This function is where we swap in
- * high performance rendering functions when the rendering
- * state allows this.
- *
- ****************************************************************************/
- {
- ibool doDither = false;
-
- /* Mandatory functions that are always the same */
- ctx->Driver.RendererString = renderer_string;
- ctx->Driver.UpdateState = setup_DD_pointers;
- ctx->Driver.ClearIndex = clear_index;
- ctx->Driver.ClearColor = clear_color;
- ctx->Driver.Clear = clear;
- ctx->Driver.Index = set_index;
- ctx->Driver.Color = set_color;
- ctx->Driver.SetBuffer = set_buffer;
- ctx->Driver.GetBufferSize = get_buffer_size;
-
- /* Driver functions that are always the same */
- ctx->Driver.Begin = begin;
- ctx->Driver.End = end;
- ctx->Driver.Flush = flush;
- ctx->Driver.Finish = finish;
- ctx->Driver.IndexMask = index_mask;
- ctx->Driver.ColorMask = color_mask;
- ctx->Driver.LogicOp = logicop;
- ctx->Driver.Dither = dither;
-
- /* Accelerated point, line and triangle functions */
- ctx->Driver.PointsFunc = mmesa_get_points_func(ctx);
- ctx->Driver.LineFunc = mmesa_get_line_func(ctx);
- ctx->Driver.TriangleFunc = mmesa_get_triangle_func(ctx);
- ctx->Driver.QuadFunc = mmesa_get_quad_func(ctx);
- ctx->Driver.RectFunc = mmesa_get_rect_func(ctx);
-
- /* Accelerated bitmap drawing functions */
- #if 0
- ctx->Driver.DrawPixels = draw_pixels;
- ctx->Driver.Bitmap = draw_bitmap;
- #endif
-
- /* Optimized pixel span reading/writing functions. Note that we use
- * a (void*) cast as we have removed the 'const'ness of the parameters
- * passed to these functions so we can use the pointers to step through
- * our arrays efficiently.
- */
- switch (RC.pixelformat) {
- case PF_INDEX:
- ctx->Driver.WriteCI32Span = (void*)(void*)_mmesa_write_span_ci;
- ctx->Driver.WriteCI8Span = (void*)_mmesa_write_span_ci8;
- ctx->Driver.WriteMonoCISpan = (void*)_mmesa_write_span_mono_ci;
- ctx->Driver.WriteCI32Pixels = (void*)_mmesa_write_pixels_ci;
- ctx->Driver.WriteMonoCIPixels = (void*)_mmesa_write_pixels_mono_ci;
- ctx->Driver.ReadCI32Span = (void*)_mmesa_read_span_ci;
- ctx->Driver.ReadCI32Pixels = (void*)_mmesa_read_pixels_ci;
- break;
- case PF_RGB8:
- ctx->Driver.WriteRGBASpan = (void*)_mmesa_write_span_8_8;
- ctx->Driver.WriteRGBSpan = (void*)_mmesa_write_span_rgb_8_8;
- ctx->Driver.WriteMonoRGBASpan = (void*)_mmesa_write_span_mono_8;
- ctx->Driver.WriteRGBAPixels = (void*)_mmesa_write_pixels_8_8;
- ctx->Driver.WriteMonoRGBAPixels = (void*)_mmesa_write_pixels_mono_8;
- ctx->Driver.ReadRGBASpan = (void*)_mmesa_read_span_8_8;
- ctx->Driver.ReadRGBAPixels = (void*)_mmesa_read_pixels_8_8;
- doDither = true;
- break;
- case PF_DITHER8:
- ctx->Driver.WriteRGBASpan = (void*)_mmesa_write_span_8_DITHER8;
- ctx->Driver.WriteRGBSpan = (void*)_mmesa_write_span_rgb_8_DITHER8;
- ctx->Driver.WriteMonoRGBASpan = (void*)_mmesa_write_span_mono_8_DITHER8;
- ctx->Driver.WriteRGBAPixels = (void*)_mmesa_write_pixels_8_DITHER8;
- ctx->Driver.WriteMonoRGBAPixels = (void*)_mmesa_write_pixels_mono_8_DITHER8;
- ctx->Driver.ReadRGBASpan = (void*)_mmesa_read_span_8_8;
- ctx->Driver.ReadRGBAPixels = (void*)_mmesa_read_pixels_8_8;
- doDither = true;
- break;
- case PF_RGB555:
- ctx->Driver.WriteRGBASpan = (void*)_mmesa_write_span_16_555;
- ctx->Driver.WriteRGBSpan = (void*)_mmesa_write_span_rgb_16_555;
- ctx->Driver.WriteMonoRGBASpan = (void*)_mmesa_write_span_mono_16;
- ctx->Driver.WriteRGBAPixels = (void*)_mmesa_write_pixels_16_555;
- ctx->Driver.WriteMonoRGBAPixels = (void*)_mmesa_write_pixels_mono_16;
- ctx->Driver.ReadRGBASpan = (void*)_mmesa_read_span_16_555;
- ctx->Driver.ReadRGBAPixels = (void*)_mmesa_read_pixels_16_555;
- break;
- case PF_DITHER555:
- ctx->Driver.WriteRGBASpan = (void*)_mmesa_write_span_16_DITHER555;
- ctx->Driver.WriteRGBSpan = (void*)_mmesa_write_span_rgb_16_DITHER555;
- ctx->Driver.WriteMonoRGBASpan = (void*)_mmesa_write_span_mono_16_DITHER555;
- ctx->Driver.WriteRGBAPixels = (void*)_mmesa_write_pixels_16_DITHER555;
- ctx->Driver.WriteMonoRGBAPixels = (void*)_mmesa_write_pixels_mono_16_DITHER555;
- ctx->Driver.ReadRGBASpan = (void*)_mmesa_read_span_16_555;
- ctx->Driver.ReadRGBAPixels = (void*)_mmesa_read_pixels_16_555;
- doDither = true;
- break;
- case PF_RGB565:
- ctx->Driver.WriteRGBASpan = (void*)_mmesa_write_span_16_565;
- ctx->Driver.WriteRGBSpan = (void*)_mmesa_write_span_rgb_16_565;
- ctx->Driver.WriteMonoRGBASpan = (void*)_mmesa_write_span_mono_16;
- ctx->Driver.WriteRGBAPixels = (void*)_mmesa_write_pixels_16_565;
- ctx->Driver.WriteMonoRGBAPixels = (void*)_mmesa_write_pixels_mono_16;
- ctx->Driver.ReadRGBASpan = (void*)_mmesa_read_span_16_565;
- ctx->Driver.ReadRGBAPixels = (void*)_mmesa_read_pixels_16_565;
- break;
- case PF_DITHER565:
- ctx->Driver.WriteRGBASpan = (void*)_mmesa_write_span_16_DITHER565;
- ctx->Driver.WriteRGBSpan = (void*)_mmesa_write_span_rgb_16_DITHER565;
- ctx->Driver.WriteMonoRGBASpan = (void*)_mmesa_write_span_mono_16_DITHER565;
- ctx->Driver.WriteRGBAPixels = (void*)_mmesa_write_pixels_16_DITHER565;
- ctx->Driver.WriteMonoRGBAPixels = (void*)_mmesa_write_pixels_mono_16_DITHER565;
- ctx->Driver.ReadRGBASpan = (void*)_mmesa_read_span_16_565;
- ctx->Driver.ReadRGBAPixels = (void*)_mmesa_read_pixels_16_565;
- doDither = true;
- break;
- case PF_RGB888:
- ctx->Driver.WriteRGBASpan = (void*)_mmesa_write_span_24_RGB;
- ctx->Driver.WriteRGBSpan = (void*)_mmesa_write_span_rgb_24_RGB;
- ctx->Driver.WriteMonoRGBASpan = (void*)_mmesa_write_span_mono_24_RGB;
- ctx->Driver.WriteRGBAPixels = (void*)_mmesa_write_pixels_24_RGB;
- ctx->Driver.WriteMonoRGBAPixels = (void*)_mmesa_write_pixels_mono_24_RGB;
- ctx->Driver.ReadRGBASpan = (void*)_mmesa_read_span_24_RGB;
- ctx->Driver.ReadRGBAPixels = (void*)_mmesa_read_pixels_24_RGB;
- break;
- case PF_BGR888:
- ctx->Driver.WriteRGBASpan = (void*)_mmesa_write_span_24_BGR;
- ctx->Driver.WriteRGBSpan = (void*)_mmesa_write_span_rgb_24_BGR;
- ctx->Driver.WriteMonoRGBASpan = (void*)_mmesa_write_span_mono_24_BGR;
- ctx->Driver.WriteRGBAPixels = (void*)_mmesa_write_pixels_24_BGR;
- ctx->Driver.WriteMonoRGBAPixels = (void*)_mmesa_write_pixels_mono_24_BGR;
- ctx->Driver.ReadRGBASpan = (void*)_mmesa_read_span_24_BGR;
- ctx->Driver.ReadRGBAPixels = (void*)_mmesa_read_pixels_24_BGR;
- break;
- case PF_ARGB8888:
- ctx->Driver.WriteRGBASpan = (void*)_mmesa_write_span_32_ARGB;
- ctx->Driver.WriteRGBSpan = (void*)_mmesa_write_span_rgb_32_ARGB;
- ctx->Driver.WriteMonoRGBASpan = (void*)_mmesa_write_span_mono_32;
- ctx->Driver.WriteRGBAPixels = (void*)_mmesa_write_pixels_32_ARGB;
- ctx->Driver.WriteMonoRGBAPixels = (void*)_mmesa_write_pixels_mono_32;
- ctx->Driver.ReadRGBASpan = (void*)_mmesa_read_span_32_ARGB;
- ctx->Driver.ReadRGBAPixels = (void*)_mmesa_read_pixels_32_ARGB;
- break;
- case PF_ABGR8888:
- ctx->Driver.WriteRGBASpan = (void*)_mmesa_write_span_32_ABGR;
- ctx->Driver.WriteRGBSpan = (void*)_mmesa_write_span_rgb_32_ABGR;
- ctx->Driver.WriteMonoRGBASpan = (void*)_mmesa_write_span_mono_32;
- ctx->Driver.WriteRGBAPixels = (void*)_mmesa_write_pixels_32_ABGR;
- ctx->Driver.WriteMonoRGBAPixels = (void*)_mmesa_write_pixels_mono_32;
- ctx->Driver.ReadRGBASpan = (void*)_mmesa_read_span_32_ABGR;
- ctx->Driver.ReadRGBAPixels = (void*)_mmesa_read_pixels_32_ABGR;
- break;
- case PF_RGBA8888:
- ctx->Driver.WriteRGBASpan = (void*)_mmesa_write_span_32_RGBA;
- ctx->Driver.WriteRGBSpan = (void*)_mmesa_write_span_rgb_32_RGBA;
- ctx->Driver.WriteMonoRGBASpan = (void*)_mmesa_write_span_mono_32;
- ctx->Driver.WriteRGBAPixels = (void*)_mmesa_write_pixels_32_RGBA;
- ctx->Driver.WriteMonoRGBAPixels = (void*)_mmesa_write_pixels_mono_32;
- ctx->Driver.ReadRGBASpan = (void*)_mmesa_read_span_32_RGBA;
- ctx->Driver.ReadRGBAPixels = (void*)_mmesa_read_pixels_32_RGBA;
- break;
- case PF_BGRA8888:
- ctx->Driver.WriteRGBASpan = (void*)_mmesa_write_span_32_BGRA;
- ctx->Driver.WriteRGBSpan = (void*)_mmesa_write_span_rgb_32_BGRA;
- ctx->Driver.WriteMonoRGBASpan = (void*)_mmesa_write_span_mono_32;
- ctx->Driver.WriteRGBAPixels = (void*)_mmesa_write_pixels_32_BGRA;
- ctx->Driver.WriteMonoRGBAPixels = (void*)_mmesa_write_pixels_mono_32;
- ctx->Driver.ReadRGBASpan = (void*)_mmesa_read_span_32_BGRA;
- ctx->Driver.ReadRGBAPixels = (void*)_mmesa_read_pixels_32_BGRA;
- break;
- }
- }
-
- /**********************************************************************/
- /***** MGLMesa API Functions *****/
- /**********************************************************************/
-
- #ifdef __WINDOWS__
- ibool APIENTRY MGLMesaInitDLL(MGLCallbacks *cb,char *version)
- /****************************************************************************
- *
- * Function: MGLMesaInitDLL
- * Parameters: cb - MGL callbacks structure
- * version - MGL version this DLL was built for
- *
- * Description: This function is called by the MGL when the MESAGL.DLL
- * library is loaded under Windows. This registers a set of
- * callback functions that Mesa uses to call MGL API functions
- * so that we dont have to staticly link the MGL and Mesa into
- * the same DLL or application.
- *
- * We also pass back a copy of Mesa's internal global MGL
- * device context which Mesa uses to directly access the MGL
- * internal functions and structures. The MGL uses this pointer
- * to maintain Mesa's internal structures
- *
- * Note that because we use the MGL's internal structures we
- * also do a check to ensure that the MGL library calling us
- * is the same version that we were built with.
- *
- ****************************************************************************/
- {
- /* Check for the correct MGL version */
- if (strcmp(version,MGL_VERSION_STR) != 0)
- return false;
- _MGL_callbacks = *cb;
- return true;
- }
- #endif
-
- void APIENTRY MGLMesaChooseVisual(MGLDC *dc,MGLVisual *visual)
- /****************************************************************************
- *
- * Function: MGLMesaChooseVisual
- * Parameters: dc - MGL device context
- * visual - Structure containing visual context information
- *
- * Description: This function examines the visual passed to use to
- * deteremine if we support the requested capabilities. If we
- * don't we will modify the structure for the capabilities that
- * we do support (ie: lowering the depth buffer size to 16
- * bits etc).
- *
- ****************************************************************************/
- {
- /* Force the depth buffer, stencil buffer and accum buffers to our sizes */
- if (visual->depth_size)
- visual->depth_size = 8 * sizeof(GLdepth);
- if (visual->stencil_size)
- visual->stencil_size = 8 * sizeof(GLstencil);
- if (visual->accum_size)
- visual->accum_size = 8 * sizeof(GLaccum);
-
- /* Force RGB mode for DirectColor and TrueColor modes */
- if (dc->mi.bitsPerPixel > 8)
- visual->rgb_flag = GL_TRUE;
- if (MGL_isMemoryDC(dc))
- visual->db_flag = GL_FALSE;
- if (MGL_isWindowedDC(dc) || MGL_surfaceAccessType(dc) == MGL_NO_ACCESS)
- visual->db_flag = GL_TRUE;
- }
-
- static int countBits(uint mask)
- /****************************************************************************
- *
- * Function: countBits
- * Parameters: mask -
- * Returns: number of set bits.
- *
- * Description: Counts the number of set bits in a mask and determines the
- * shift amount.
- *
- ****************************************************************************/
- {
- int i=0;
-
- if (mask) {
- /* count set bits */
- while ( mask & (1 << i)) {
- i++;
- };
- }
-
- return i;
- }
-
- ibool APIENTRY MGLMesaSetVisual(MGLDC *dc,MGLVisual *vis)
- /****************************************************************************
- *
- * Function: MGLMesaSetVisual
- * Parameters: dc - MGL device context
- * visual - Structure containing visual context information
- * Returns: True on success, false if visual creation failed
- *
- * Description: This function attempts to create a Mesa visual for the
- * device context. If this succeeds then Mesa can properly
- * handle the requested visual.
- *
- ****************************************************************************/
- {
- GLfloat red_scale, green_scale, blue_scale, alpha_scale;
- GLint red_bits, green_bits, blue_bits, alpha_bits;
-
- /* Do quick check on incoming visual */
- if (dc->mi.bitsPerPixel > 8 && !vis->rgb_flag)
- return false;
- if (dc->mi.bitsPerPixel < 8)
- return false;
- if ((dc->mi.xRes+1 > MAX_WIDTH) || (dc->mi.yRes+1 > MAX_HEIGHT))
- return false;
- if (MGL_isMemoryDC(dc) && vis->db_flag)
- return false;
- if ((MGL_isWindowedDC(dc) || MGL_surfaceAccessType(dc) == MGL_NO_ACCESS) && !vis->db_flag)
- return false;
-
- /* Create color channel scale factors from pixel format info */
- red_scale = (GLfloat)dc->pf.redMask;
- green_scale = (GLfloat)dc->pf.greenMask;
- blue_scale = (GLfloat)dc->pf.blueMask;
- alpha_scale = 255.0;
-
- red_bits = countBits(dc->pf.redMask);
- green_bits = countBits(dc->pf.greenMask);
- blue_bits = countBits(dc->pf.blueMask);
- alpha_bits = countBits(dc->pf.rsvdMask);
-
- MGL_clearCurrentDC();
- dc->visual = gl_create_visual( vis->rgb_flag,
- vis->alpha_flag,
- vis->db_flag,
- GL_FALSE, /* stereo */
- vis->depth_size,
- vis->stencil_size,
- vis->accum_size,
- dc->mi.bitsPerPixel,
- red_bits,
- green_bits,
- blue_bits,
- alpha_bits);
- return (dc->visual != NULL);
- }
-
- ibool APIENTRY MGLMesaCreateContext(MGLDC *dc,ibool forceMemDC)
- /****************************************************************************
- *
- * Function: MGLMesaCreateContext
- * Parameters: dc - MGLDC to create rendering context for
- * forceMemDC - True to force rendering to memory back buffer
- * Returns: True on success, false on failure.
- *
- * Description: Attempts to create a Mesa rendering context for the
- * device context. The application programmer must first
- * call MGLMesaSetVisual on the MGLDC to set the visual format
- * before calling this function.
- *
- * If we dont have hardware page flipping or the user has
- * forced memory buffering with the forceMemDC function then
- * we will allocate a system memory back buffer for double
- * buffering. Note that if we have hardware page flipping
- * and system buffering has been forced, we will still flip
- * between hardware pages to eliminate all tearing. This
- * option is intended mainly as a performance option for
- * systems where system memory rendering is faster.
- *
- ****************************************************************************/
- {
- palette_t pal[256];
-
- /* Ensure that the visual has been created first */
- MGL_clearCurrentDC();
- if (!dc->visual)
- return false;
-
- /* Allocate memory for the rendering context structure and create it */
- if ((dc->rc = (void*)calloc(1,sizeof(MGLRC))) == NULL)
- goto Error;
- dc->rc->dispdc = dc;
- dc->rc->gl_ctx = gl_create_context(dc->visual,NULL,(void*)dc->rc, GL_TRUE);
- if (!dc->rc)
- goto Error;
-
- /* Allocate the ancillary buffers */
- if ((dc->rc->gl_buffer = gl_create_framebuffer(dc->visual)) == NULL)
- goto Error;
-
- /* Allocate back memory DC buffer if necessary */
- if ((dc->visual->DBflag && dc->mi.maxPage == 0) || forceMemDC || (MGL_surfaceAccessType(dc) == MGL_NO_ACCESS)) {
- dc->rc->memdc = MGL_createMemoryDC(dc->mi.xRes+1,dc->mi.yRes+1,dc->mi.bitsPerPixel,&dc->pf);
- if (!dc->rc->memdc)
- goto Error;
- dc->rc->dc = dc->rc->memdc;
- }
- else
- dc->rc->dc = dc->rc->dispdc;
-
- /* Initialize double buffering */
- if (dc->visual->DBflag && dc->mi.maxPage > 0) {
- MGL_setVisualPage(dc,dc->rc->frontbuffer = 0,false);
- MGL_setActivePage(dc,dc->rc->backbuffer = 1);
- }
-
- /* Initialize the private rendering context information */
- if (!dc->visual->RGBAflag) {
- dc->rc->dithered_pf = dc->rc->undithered_pf = PF_INDEX;
- MGL_getPalette(dc,pal,256,0);
- }
- else {
- if (dc->mi.bitsPerPixel > 8) {
- /* DirectColor or TrueColor display */
- if (dc->mi.bitsPerPixel == 15) {
- dc->rc->undithered_pf = PF_RGB555;
- dc->rc->dithered_pf = PF_DITHER555;
- }
- else if (dc->mi.bitsPerPixel == 16) {
- dc->rc->undithered_pf = PF_RGB565;
- dc->rc->dithered_pf = PF_DITHER565;
- }
- else if (dc->mi.bitsPerPixel == 24) {
- if (dc->pf.redPos == 0)
- dc->rc->undithered_pf = dc->rc->dithered_pf = PF_BGR888;
- else
- dc->rc->undithered_pf = dc->rc->dithered_pf = PF_RGB888;
- }
- else {
- if (dc->pf.redPos == 0)
- dc->rc->undithered_pf = dc->rc->dithered_pf = PF_ABGR8888;
- else if (dc->pf.redPos == 8)
- dc->rc->undithered_pf = dc->rc->dithered_pf = PF_BGRA8888;
- else if (dc->pf.redPos == 16)
- dc->rc->undithered_pf = dc->rc->dithered_pf = PF_ARGB8888;
- else
- dc->rc->undithered_pf = dc->rc->dithered_pf = PF_RGBA8888;
- }
- }
- else {
- /* 8bpp RGB display */
- dc->rc->undithered_pf = PF_RGB8;
- dc->rc->dithered_pf = PF_DITHER8;
- MGL_getHalfTonePalette(pal);
- }
- }
- dc->rc->gl_vis = dc->visual;
- dc->rc->bottom = dc->mi.yRes+1;
- dc->rc->pixelformat = dc->rc->dithered_pf;
- dc->rc->bufferMode = dc->visual->DBflag ? GL_BACK : GL_FRONT;
- setup_DD_pointers(dc->rc->gl_ctx);
-
- /* Setup the default palette for the device context */
- if (dc->mi.bitsPerPixel == 8) {
- MGLMesaSetPalette(dc,pal,256,0);
- MGLMesaRealizePalette(dc,256,0,false);
- }
- return true;
-
- Error:
- MGLMesaDestroyContext(dc);
- return false;
- }
-
- void APIENTRY MGLMesaDestroyContext(MGLDC *dc)
- /****************************************************************************
- *
- * Function: MGLMesaDestroyContext
- * Parameters: dc - MGLDC to destroy rendering context for
- *
- * Description: Destroys the rendering context and returns the MGLDC back
- * to it's original state before 3D rendering was enabled.
- *
- ****************************************************************************/
- {
- if (dc->rc) {
- if (dc->rc->memdc)
- MGL_destroyDC(dc->rc->memdc);
- gl_destroy_framebuffer(dc->rc->gl_buffer);
- gl_destroy_context(dc->rc->gl_ctx);
- free(dc->rc);
- }
- dc->rc = NULL;
- gl_destroy_visual(dc->visual);
- dc->visual = NULL;
- }
-
- void APIENTRY MGLMesaMakeCurrent(MGLDC *dc)
- /****************************************************************************
- *
- * Function: MGLMesaMakeCurrent
- * Parameters: dc - MGLDC to make current
- *
- * Description: Makes the passed in MGLDC the current rendering context
- * for OpenGL functions. Note that we cache a global copy
- * of this rendering context for speed (we are single threaded)
- * so we flush this back when the context is made a different
- * one.
- *
- ****************************************************************************/
- {
- if (dc && dc->rc == _MM_rcPtr)
- return;
- if (_MM_rcPtr) {
- *_MM_rcPtr = RC; /* 'Write back' the old RC */
- _MM_rcPtr = NULL; /* This RC is no longer cached */
- gl_make_current(NULL, NULL);
- MGL_clearCurrentDC();
- }
- if (dc) {
- gl_make_current(dc->rc->gl_ctx, dc->rc->gl_buffer);
- _MM_rcPtr = dc->rc; /* Cache DC in global structure */
- RC = *dc->rc; /* Save pointer to original DC */
- MI = RC.dc->mi; /* Save cached MGL internals */
- PF = RC.dc->pf;
- VECS = RC.dc->r;
- set_buffer(dc->rc->gl_ctx,RC.bufferMode);
- if (RC.gl_ctx->Viewport.Width == 0) {
- /* initialize viewport to window size */
- gl_Viewport(RC.gl_ctx, 0, 0, MI.xRes+1, MI.yRes+1);
- RC.gl_ctx->Scissor.Width = MI.xRes+1;
- RC.gl_ctx->Scissor.Height = MI.yRes+1;
- }
- }
- }
-
- void APIENTRY MGLMesaSwapBuffers(MGLDC *dc,ibool waitVRT)
- /****************************************************************************
- *
- * Function: MGLMesaSwapBuffers
- * Parameters: dc - MGLDC to swap buffers for
- * waitVRT - True to wait for vertical retrace
- *
- * Description: Swaps the display buffers for the MGL device context. If
- * we have a memory DC this is blitted to the display, and
- * if we have harware page flipping we flip hardware display
- * pages.
- *
- ****************************************************************************/
- {
- if (!RC.gl_vis->DBflag)
- return;
- if (RC.memdc) {
- /* We have a memory buffer so blit it to the screen */
- MGL_bitBltCoord(RC.dispdc,RC.memdc,0,0,MI.xRes+1,MI.yRes+1,0,0,MGL_REPLACE_MODE);
- }
- if (RC.dc->mi.maxPage > 0) {
- /* Hardware page flipping */
- RC.frontbuffer ^= 1;
- RC.backbuffer = RC.frontbuffer ^ 1;
- if (RC.bufferMode == GL_FRONT)
- MGL_setActivePage(RC.dc,RC.frontbuffer);
- else
- MGL_setActivePage(RC.dc,RC.backbuffer);
- MGL_setVisualPage(RC.dc,RC.frontbuffer,waitVRT);
- }
- }
-
- void APIENTRY MGLMesaSetPaletteEntry(MGLDC *dc,int entry,uchar red,uchar green,uchar blue)
- /****************************************************************************
- *
- * Function: MGLMesaSetPaletteEntry
- * Parameters: dc - MGLDC to destroy rendering context for
- * entry - Index of entry to set
- * red,... - Color values for palette entry
- *
- * Description: Sets a single color palette entry in the device context.
- *
- ****************************************************************************/
- {
- MGL_setPaletteEntry(dc,entry,red,green,blue);
- if (dc->rc && dc->rc->memdc)
- MGL_setPaletteEntry(dc->rc->memdc,entry,red,green,blue);
- }
-
- void APIENTRY MGLMesaSetPalette(MGLDC *dc,palette_t *pal,int numColors,int startIndex)
- /****************************************************************************
- *
- * Function: MGLMesaDestroyContext
- * Parameters: dc - MGLDC to destroy rendering context for
- *
- * Description: Destroys the rendering context and returns the MGLDC back
- * to it's original state before 3D rendering was enabled.
- *
- ****************************************************************************/
- {
- MGL_setPalette(dc,pal,numColors,startIndex);
- if (dc->rc && dc->rc->memdc)
- MGL_setPalette(dc->rc->memdc,pal,numColors,startIndex);
- }
-
- void APIENTRY MGLMesaRealizePalette(MGLDC *dc,int numColors,int startIndex,int waitVRT)
- /****************************************************************************
- *
- * Function: MGLMesaDestroyContext
- * Parameters: dc - MGLDC to destroy rendering context for
- *
- * Description: Destroys the rendering context and returns the MGLDC back
- * to it's original state before 3D rendering was enabled.
- *
- ****************************************************************************/
- {
- MGL_realizePalette(dc,numColors,startIndex,waitVRT);
- if (dc->rc && dc->rc->memdc)
- MGL_realizePalette(dc->rc->memdc,numColors,startIndex,waitVRT);
- }
-
-